package cn.aylog.test;

import cn.alog.pojo.Person;
import cn.alog.utils.EsUtils;
import com.alibaba.fastjson.JSON;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Demo1 {
    String index = "person";

    /**
     * 测试连接
     */
    @Test
    public void run1() {
        RestHighLevelClient client = EsUtils.getClient();
        System.out.println("ok!!");
    }

    /**
     * 测试增加文档
     */
    @Test
    public void create() throws IOException {
        // 准备settings
        Settings.Builder settings = Settings.builder()
                .put("number_of_replicas", 1)
                .put("number_of_shards", 1);

        // 准备mappings
        XContentBuilder mappings = JsonXContent.contentBuilder()
                .startObject()
                .startObject("properties")
                .startObject("name")
                .field("type", "keyword")
                .endObject()
                .startObject("age")
                .field("type", "long")
                .endObject()
                .startObject("birthday")
                .field("type", "date")
                .field("format", "yyyy-MM-dd")
                .endObject()
                .endObject()
                .endObject();
        // 构建请求参数
        CreateIndexRequest request = new CreateIndexRequest(index)
                .settings(settings)
                .mapping(mappings);
        // 获取连接客户端
        RestHighLevelClient client = EsUtils.getClient();
        // 创建索引
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        //
        System.out.println(response);
    }

    /**
     * 检测指定索引是否存在
     * @throws IOException
     */
    @Test
    public void exists() throws IOException {
        // 根据client.indices().exists创建所需请求参数
        GetIndexRequest request = new GetIndexRequest(index);
        // 获取链接客户端
        RestHighLevelClient client = EsUtils.getClient();
        // 执行
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        // 输出
        System.out.println(exists);
    }


    /**
     * 删除索引
     */
    @Test
    public void delete() throws IOException {
        // 创建请求参数
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        // 获取连接客户端
        RestHighLevelClient client = EsUtils.getClient();
        // 操作
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        // 输出
        System.out.println(delete.isAcknowledged());
    }
    /**
     * 增加数据
     */
    @Test
    public void add() throws IOException {
        // 创建数据
        Person person = new Person(1,"张三",18,new Date());
        //数据转换
        String json = JSON.toJSONString(person);
        //构建请求
        IndexRequest request = new IndexRequest(index);
        request.source(json, XContentType.JSON);
        request.id(person.getId().toString());
        // 获取客户端
        IndexResponse index = EsUtils.getClient().index(request, RequestOptions.DEFAULT);
        //输出
        System.out.println(index);
    }

    /**
     * 更新数据
     */
    @Test
    public void update() throws IOException {
        // 创建修改的参数
        Map<String,Object> map = new HashMap<>();
        map.put("name", "张大三");
        // 构建参数
        UpdateRequest request = new UpdateRequest(index,"1");
        request.doc(map);
        // 执行
        UpdateResponse response = EsUtils.getClient().update(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }

    /**
     * 删除数据
     */
    @Test
    public void remove() throws IOException {
        // 构建参数
        DeleteRequest request = new DeleteRequest(index, "1");
        // 执行
        DeleteResponse response = EsUtils.getClient().delete(request, RequestOptions.DEFAULT);
        // 输出
        System.out.println(response);
    }

    /**
     * 批量添加
     */
    @Test
    public void bulkAdd() throws IOException {
        // 构建数据
        Person p1 = new Person(1,"张大三",23,new Date());
        Person p2 = new Person(2,"张一山",24,new Date());
        Person p3 = new Person(3,"大张伟",25,new Date());

        String json1 = JSON.toJSONString(p1);
        String json2 = JSON.toJSONString(p2);
        String json3 = JSON.toJSONString(p3);
        // 构建请求参数
        BulkRequest request = new BulkRequest(index);
        request.add(new IndexRequest(index).id(p1.getId().toString()).source(json1,XContentType.JSON));
        request.add(new IndexRequest(index).id(p2.getId().toString()).source(json2,XContentType.JSON));
        request.add(new IndexRequest(index).id(p3.getId().toString()).source(json3,XContentType.JSON));
        // 执行
        BulkResponse bulk = EsUtils.getClient().bulk(request, RequestOptions.DEFAULT);
        // 输出
        System.out.println(bulk);
    }

    /**
     * 批量删除
     */
    @Test
    public void bulkRemove() throws IOException {
        // 构建参数
        BulkRequest request = new BulkRequest();
        request.add(new DeleteRequest(index,"1"));
        request.add(new DeleteRequest(index,"2"));
        request.add(new DeleteRequest(index,"3"));
        // 执行
        BulkResponse bulk = EsUtils.getClient().bulk(request, RequestOptions.DEFAULT);
        System.out.println(bulk);
    }

    /**
     * term查询
     */
    @Test
    public void term() throws IOException {
        // 构建参数
        SearchRequest request = new SearchRequest(index);
        // 添加请求参数
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.from(0);
        builder.size(5);
        builder.query(QueryBuilders.termQuery("name.keyword","张三"));

        request.source(builder);
        // 操作
        SearchResponse response = EsUtils.getClient().search(request, RequestOptions.DEFAULT);
        // 输出
        for (SearchHit hit : response.getHits().getHits()) {
            Map<String, Object> source = hit.getSourceAsMap();
            System.out.println(source);
        }
    }

    /**
     * terms查询
     */
    @Test
    public void terms() throws IOException {
        // 构建参数
        SearchRequest request = new SearchRequest(index);
        // 参数拼接
        SearchSourceBuilder search = new SearchSourceBuilder();
        search.from(0);
        search.size(5);
        search.query(QueryBuilders.termsQuery("name.keyword","张三","张大三","大张伟"));
        request.source(search);
        // 操作
        SearchResponse response = EsUtils.getClient().search(request, RequestOptions.DEFAULT);

        // 输出
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    /**
     * match_all查询
     */
    @Test
    public void matchAll() throws IOException {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());
        request.source(builder);
        SearchResponse response = EsUtils.getClient().search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    /**
     * match查询
     */
    @Test
    public void match() throws IOException {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("name","张"));
        request.source(builder);
        SearchResponse response = EsUtils.getClient().search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    /**
     * booleanMatch查询
     */
    @Test
    public void booleanMatch() throws IOException {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("name","张 三").operator(Operator.AND));
        request.source(builder);
        SearchResponse response = EsUtils.getClient().search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    /**
     * multiMatch查询
     */
    @Test
    public void multiMatch() throws IOException {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.multiMatchQuery("三","name"));
        request.source(builder);
        SearchResponse response = EsUtils.getClient().search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    /**
     * id查询
     */
    @Test
    public void id() throws IOException {
        // 构建参数
        GetRequest request = new GetRequest(index, "1");
        // 执行
        GetResponse response = EsUtils.getClient().get(request, RequestOptions.DEFAULT);
        // 输出
        System.out.println(response.getSourceAsMap());
    }

    /**
     * ids查询
     */
    @Test
    public void ids() throws IOException {
        // 构建参数
        SearchRequest request = new SearchRequest(index);
        // 参数填充
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.idsQuery().addIds("1","2"));
        request.source(builder);
        // 执行
        SearchResponse search = EsUtils.getClient().search(request, RequestOptions.DEFAULT);
        // 输出结果
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    /**
     * prefix查询
     */
    @Test
    public void prefix() throws IOException {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder  = new SearchSourceBuilder();
        builder.query(QueryBuilders.prefixQuery("name","张"));
        request.source(builder);
        SearchResponse search = EsUtils.getClient().search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    /**
     * fuzzy查询
     */
    @Test
    public void fuzzy() throws IOException {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder  = new SearchSourceBuilder();
        builder.query(QueryBuilders.fuzzyQuery("name","三").prefixLength(1));
        request.source(builder);
        SearchResponse search = EsUtils.getClient().search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }
}
